package cn.codeforfun.client.data;

import cn.codeforfun.client.constants.DataSourceProperties;
import cn.hutool.core.date.DateUtil;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Date;
import java.util.List;

@Component
@Import({DataSourceProperties.class})
public class MySQLHandler implements DataHandler {
    @Resource
    DataSourceProperties dataSourceProperties;
    @Resource
    org.springframework.boot.autoconfigure.jdbc.DataSourceProperties properties;

    @Bean(name = "dataSourceForDiscoveryClient")
    public DataSource dataSourceForDiscoveryClient() {
        DataSourceBuilder<?> builder = DataSourceBuilder.create();
        if (dataSourceProperties.getUsername() == null || dataSourceProperties.getUrl() == null) {
            builder.type(properties.getType());
            builder.driverClassName(properties.getDriverClassName());
            builder.url(properties.getUrl());
            builder.username(properties.getUsername());
            builder.password(properties.getPassword());
        } else {
            builder.type(dataSourceProperties.getType());
            builder.driverClassName(dataSourceProperties.getDriverClassName());
            builder.url(dataSourceProperties.getUrl());
            builder.username(dataSourceProperties.getUsername());
            builder.password(dataSourceProperties.getPassword());
        }
        return builder.build();
    }

    @Bean(name = "jdbcTemplateForDiscoveryClient")
    public JdbcTemplate jdbcTemplateForDiscoveryClient(DataSource dataSourceForDiscoveryClient) {
        return new JdbcTemplate(dataSourceForDiscoveryClient);
    }

    @Resource
    JdbcTemplate jdbcTemplateForDiscoveryClient;

    @Override
    public void registerService(ServiceInstance serviceInstance) {
        activeCurrentService(serviceInstance);
    }

    @Override
    public void activeService(ServiceInstance serviceInstance) {
        activeCurrentService(serviceInstance);
    }

    private void activeCurrentService(ServiceInstance serviceInstance) {
        String sql = "insert into cff_service (name, host, port, last_active) value (?, ?, ?, now()) " +
                "on duplicate key update last_active=now()";
        jdbcTemplateForDiscoveryClient.update(sql, serviceInstance.getName(), serviceInstance.getHost(), serviceInstance.getPort());
    }

    @Override
    public List<ServiceInstance> findServiceInstanceList(Integer serviceActiveTimeout) {
        long time = DateUtil.offsetSecond(new Date(), -serviceActiveTimeout).getTime();
        String sql = "select name, remark, host, port, last_active from cff_service where last_active > ?";
        return jdbcTemplateForDiscoveryClient.query(sql, (rs, rowNum) -> {
            ServiceInstance serviceInstance = new ServiceInstance();
            serviceInstance.setName(rs.getString("name"));
            serviceInstance.setRemark(rs.getString("remark"));
            serviceInstance.setHost(rs.getString("host"));
            serviceInstance.setPort(rs.getInt("port"));
            serviceInstance.setLastActive(new Date(rs.getTimestamp("last_active").getTime()));
            return serviceInstance;
        }, time);
    }

    @Override
    public void deregisterService(ServiceInstance serviceInstance) {
        String sql = "delete " +
                "from cff_service " +
                "where name = ? " +
                "  and host = ? " +
                "  and port = ?";
        jdbcTemplateForDiscoveryClient.update(sql, serviceInstance.getName(), serviceInstance.getHost(), serviceInstance.getPort());
    }
}
